<?php

class PermissaoController extends AdminController implements ItemMenu {

	public function cadastrar(){
		
		if( isset($_POST) && count($_POST) > 0 ){ 
			
			$this->salvar();
		
		}else{
		
			$view = new View("permissao/gerenciar");
			
			// Form
			$view->set("form.title.action", ucfirst( $this->getAction() ));
			$view->set("form.action", $this->getAction() );
			$view->set("form.image", "disk" );
			$view->set("form.lenght", "3" ); // 1, 2, 3 or 4
			
			// Internal form
			$view->set("cancelar.controller", $this->getController());
			$view->set("ativo.checked", "checked");
			$view->set("ativo.disabled", "disabled");
			$view->set("nome.disabled", "");
			$view->set("tipo.permissao.id", "" );
			$view->set("nome", "");
			
			$permissoes  = ViewList::merge( "permissao/form_line", $this->montarPermissoesCheckboxes($this->mainMenu) );		
			$permissoes .= ViewList::merge( "permissao/form_line_check",  $this->prepareNotItemMenu() );
			
			$view->set("permissoes", $permissoes );
			$this->template->content = $view;
		
		}
		
	}
		
	public function editar($hasSubmit=true){
		
		if( isset($_POST) && count($_POST) > 0 ){ 
			
			$this->salvar();
		
		}else{
			
			$idParam = $this->getIdFrom("tipo_permissao_id"); //($this->isAdministrador()) ? $this->getParam("id") : $this->auth->getUserData("tipo_permissao_id") ;
		
			if( $this->testIsValidId($idParam) ){
			
				$view = new View("permissao/gerenciar");
				
				$tipoPermissaoId = $idParam; //1; //$this->auth->getUserData("tipo_permissao_id");
				$permissaoModel = new PermissaoModel();
				$permissoes = $permissaoModel->find( array( "tipo_permissao_id" => $tipoPermissaoId ) );
				$tipoPermissaoModel = new TipoPermissaoModel();
				$tipoPermissao = $tipoPermissaoModel->findById( $tipoPermissaoId ); 
				
				// Form
				$view->set("form.title.action", ( ($this->getAction() != "index") ? ucfirst($this->getAction()) : "Ver") );
				$view->set("form.action", ($hasSubmit) ? $this->getAction() : "#" );
				$view->set("form.image", ($hasSubmit) ? "pencil" : "eye" );
				$view->set("form.lenght", "3" ); // 1, 2, 3 or 4
				$view->set("form.buttons.display", ($hasSubmit) ? "block" : "none");
				
				// Internal form
				$view->set("cancelar.controller", ($hasSubmit || $this->isAdministrador()) ? $this->getController(): "" );
				$view->set("nome.disabled", "disabled");
				$view->set("ativo.disabled", ($hasSubmit) ? "" : "disabled");
				$view->set("ativo.checked", ($tipoPermissao['ativo'] == 1) ? "checked" : "" );
				$view->set("tipo.permissao.id", ($hasSubmit) ? Encryption::encode($tipoPermissao['id']) : "" );
				$view->set("nome", $tipoPermissao['nome']);

				$permissoesParam  = ViewList::merge( "permissao/form_line", $this->montarPermissoesCheckboxes( $this->mainMenu, $permissoes, $hasSubmit ) );
				$permissoesParam .= ViewList::merge( "permissao/form_line_check",  $this->marcarPermissoesChecked( $this->prepareNotItemMenu(), $permissoes, $hasSubmit ) );
				
				$view->set("permissoes", $permissoesParam );
				$this->template->content = $view;
				
			}else{
				
				$this->redirecionaAcessoIdInvalido("Perfil de Permissões", "permissao");
							
			}
			
		}
		
	}
	
	public function listar() {
		
		$view = new View("_components/jquery_table");
		
		$view->set("table.title", "Todos os Perfis de Permissões");
		$view->set("table.black.icon16", "list");
		$view->set("table.new.label", "Novo Perfil");
		$view->set("table.new.url", "permissao/cadastrar");
		
		$view->set("table.head", 
			ViewList::merge( "th",
				TipoPermissaoModel::createHeadersToTable()
			) 
		);
		
		$view->set("table.body", 
			ViewList::merge( "permissao/tr", 
				TipoPermissaoModel::listAllToTable( $this->createArrayControllerRotulo() )
			) 
		);
		
		$this->template->content = $view;
	
	}

	public function apagar() {
		
		$idParam = $this->getIdFrom("tipo_permissao_id"); //($this->isAdministrador()) ? $this->getParam("id") : $this->auth->getUserData("tipo_permissao_id") ;
	
		if( $this->testIsValidId($idParam) ){
		
			$tipoPermissaoModel = new TipoPermissaoModel();
			$tipoPermissao = $tipoPermissaoModel->delete($idParam);
			
			$this->addGrowlMsgs( Messages::get("apagadoComSucesso", array( "{objeto}" => $tipoPermissao['nome'] )) );
			$this->redirect->goToAction("index");
			
		}else{
			
			$this->redirecionaAcessoIdInvalido("Perfil de Permissões", "permissao");
						
		}
		
	}

	public function ver() {
		$this->editar(false);
	}

	// Public Static section ======================================================================

	public static final function getReflectionClass($controller) {
		$api = new ReflectionClass( ucfirst($controller)."Controller" );
		return $api;
	}
	
	public static final function getActionsArrayItemMenu(ReflectionClass $api) {
	
		$methods = $api->getMethods( ReflectionMethod::IS_PUBLIC );
		$response = array();
		foreach($methods as $method){
			$nome = $method->getName();
			// actions são verbos e terminam em 'r'
		    if( ( (substr($nome, (strlen($nome)-1), 1) == "r") && ($nome != "getController") ) || $nome == "index" )
				$response[] =  $nome;
		}
		return $response;
		
	}
	
	public static final function getActionsArrayNotItemMenu(ReflectionClass $api) {
	
		$methods = $api->getMethods( ReflectionMethod::IS_PUBLIC );
		$response = array();
		foreach($methods as $method){
			$nome = $method->getName();
			// actions são verbos e terminam em 'r'
		    if( ($nome != "getController") )
				$response[] =  $nome;
		}
		return $response;
		
	}
	
	public static final function inBasicSystem($controller) {
		$controllerClassName = ucfirst($controller)."Controller";
		$obj = new $controllerClassName();
		return $obj->containsBasicSystem($controller);
	}

	// Private section ============================================================================
	
	private function marcarPermissoesChecked($todasPermissoes, $checkedPermissoes, $hasSubmit=true) {
		$escape = false;
		$permissaoFinal = array();
		// Percorre todas as permissões
		foreach( $todasPermissoes as $index => $permissao ){
			// Percorre as permissões vindas do banco
			foreach ($checkedPermissoes as $indexChecked => $permissaoChecked) {
				// Se encontrar uma permissão para selecionar atualiza '$permissaoFinal'
				if( $permissao['controller'] == $permissaoChecked['controller'] ){
					$actions = explode("-", $permissaoChecked['actions']);
					foreach ($actions as $action){
						$permissao["checked.".$action] = "checked";
					}
					unset( $checkedPermissoes[ $indexChecked ] );
				}
				if( count($checkedPermissoes) == 0 ){
					$escape = true;
					break;
				}
			}
			$permissao["check.disabled"] = ($hasSubmit) ? "" : "disabled";
			$permissaoFinal[] = $permissao;
			if( $escape )
				break;
		}
		return $permissaoFinal;
	}
	
	private function getMetodosController($controller) {
	
		$response = array();
		$api = new ReflectionClass( ucfirst($controller)."Controller" );
		$methods = $api->getMethods( ReflectionMethod::IS_PUBLIC );
		foreach($methods as $method){
			$nome = $method->getName();
			// actions são verbos e terminam em 'r'
		    if( (substr($nome, (strlen($nome)-1), 1) == "r") && ($nome != "getController") && ($nome != "salvar") )
				$response[] =  array( "action.name" => $nome, "action.label" => ucfirst($nome) );
		}
		return $response;
		
	}
	
	private function montarPermissoesCheckboxes($todasPermissoes, $checkedPermissoes=array(), $hasSubmit=true) {
		$escape = false;
		$permissaoFinal = array();
		// Percorre todas as permissões
		foreach( $todasPermissoes as $index => $permissao ){
			// Adiciona checks no inicio do array
			$permissao = array_merge( array( "checks" => "" ), $permissao );
			// Percorre as permissões vindas do banco
			$checks = ViewList::merge( "permissao/check", $this->getMetodosController($permissao['controller']) );
			foreach ($checkedPermissoes as $indexChecked => $permissaoChecked) {
				// Se encontrar uma permissão para selecionar atualiza '$permissaoFinal'
				if( $permissao['controller'] == $permissaoChecked['controller'] ){
					$actions = explode("-", $permissaoChecked['actions']);
					foreach ($actions as $action){
						$permissao["checked.".$action] = "checked";
					}
					unset( $checkedPermissoes[ $indexChecked ] );
				}
				if( count($checkedPermissoes) == 0 ){
					$escape = true;
					break;
				}
			}
			$permissao["check.disabled"] = ($hasSubmit) ? "" : "disabled";
			$permissao["checks"] = $checks;
			$permissaoFinal[] = $permissao;
			if( $escape )
				break;
		}
		return $permissaoFinal;
	}
	
	private function prepareNotItemMenu() {
		$notItemMenu = array_merge( 
			$this->basicSystem, 
			$this->notItemMenu 
		);
		return $notItemMenu;
	}
	
	private function salvar(){
	
//		// Verifica se houve POST
//		if( isset($_POST) && count($_POST) > 0 ){
			
			// Verifica se veio algum dado válido para a operação
			if( empty($_POST['id']) && empty($_POST['nome']) ){
				$this->addGrowlMsgs( Messages::get('dadosInvalidos',array("{objeto}" => "Perfil de Permissões")) );
				$this->redirect->goToUrl("permissao");
				exit();
			}
			
			$idForm = Encryption::decode($_POST['id']);
			$tipoPermissao = array("id" => $idForm);
			$isNovo = false;
			
			$tipoPermissaoModel = new TipoPermissaoModel();
			$tipoPermissao = $tipoPermissaoModel->find($tipoPermissao);
			
			// Verifica se é um novo registro e tenta adicioná-lo se possível
			if( !empty($_POST['nome']) && count($tipoPermissao) == 0 ){
			
				$tipoPermissaoExample = array( "nome" => $_POST['nome'] );
				
				if( empty($idForm) ){
					$response = $tipoPermissaoModel->find($tipoPermissaoExample);
					if( count($response) == 0 ){
						$tipoPermissao = $tipoPermissaoModel->persist($tipoPermissaoExample);
						$idForm = $tipoPermissao['id'];
						$isNovo = true;
					}else {
						$this->addGrowlMsgs( Messages::get("campoDuplicado", array("{campo}" => "'Nome do Perfil'")) );
						$this->redirect->goToAction("cadastrar");
						exit();
					}
				}

			// Verifica se o registro já existe e seleciona-o
			}else if( count($tipoPermissao) != 0 ){
				
				$tipoPermissao = $tipoPermissao[0];
				$tipoPermissao['ativo'] = isset($_POST['ativo']) ? 1 : 0;
				$tipoPermissaoModel->merge($tipoPermissao);
				
			}
			
			// Verifica se a identificação atualizada do id(TipoPermissao) é válida
			if( !is_numeric($idForm) ){
				$this->addGrowlMsgs( Messages::get("idInvalido", array( "{objeto}" => "Perfil de Permissões" )) );
				$this->redirect->goToUrl("permissao");
				exit();
			}
			
			$permissoesPost = array();
			$i = 0;
			
			// Prepara as configurações de permissões que vieram por POST
			foreach ($_POST as $key => $value){
				if( is_array($value) ){
					$permissoesPost[$i] = array( "tipo_permissao_id" => $tipoPermissao['id'] );
					$permissoesPost[$i][ 'controller' ] = $key;
					$permissoesPost[$i][ 'actions' ] = implode("-", $value);
					// Adiciona permissão à action index para todos
					if( !in_array("index", $value) )
						$permissoesPost[$i][ 'actions' ] .= "-index";
					// Adiciona permissão à action listar para todos que tem permissão à apagar
					if( in_array("apagar", $value) && !in_array("listar", $value) )
						$permissoesPost[$i][ 'actions' ] .= "-listar";
					$i++;
				}else{
					if( $key != "nome" && $key != "id" && $key != "ativo" ){
						$permissoesPost[$i] = array( "tipo_permissao_id" => $tipoPermissao['id'] );
						$permissoesPost[$i][ 'controller' ] = $key;
						$permissoesPost[$i][ 'actions' ] = $value;
						$i++;
					}
				}
			}
			
			$permissaoModel = new PermissaoModel();
			$permissoesDB = $permissaoModel->find( array( "tipo_permissao_id" => $tipoPermissao['id'] ) );
			
			// Verifica se já existem permissões para este perfil
			if( count($permissoesDB) > 0 ){

				// Percorre as permissões vindas por POST
				foreach ($permissoesPost as $indexPost => $permissaoPost){
					// Verifica se há permissões a atualizar
					if( count($permissoesDB) > 0 ){
						$salvou = false;
						// Percorre as permissões já existentes
						foreach ($permissoesDB as $indexDB => $permissaoDB){
							// Se encontrar uma permissão pré-existente para uma mesma área, 
							// realiza a atualização na variável '$permissaoPost' e exclui
							// do array '$permissoesDB' para otimizar próximas buscas
							if( $permissaoPost['controller'] == $permissaoDB['controller'] ){
								$permissaoPost['id'] = $permissaoDB['id'];
								$permissaoModel->merge( $permissaoPost );
								unset( $permissoesDB[ $indexDB ] );
								$salvou = true;
								break;
							}
						}
						if( !$salvou )
							$permissaoModel->persist( $permissaoPost );
					// Se não há mais permissões a atualizar, simplesmente insere
					}else{
						// Insere no banco
						$permissaoModel->persist( $permissaoPost );
					}
				}
			
				// Caso ainda reste permissões inalteradas no banco, remove-as
				if( count($permissoesDB) > 0 )
					foreach ($permissoesDB as $permissaoDB)
						$permissaoModel->delete( $permissaoDB['id'], true );
			
			// Caso seja um perfil novo, apenas insere as permissões
			}else{
				
				foreach ($permissoesPost as $indexPost => $permissaoPost)
					$permissaoModel->persist( $permissaoPost );
						
			}
			
			// Define a mensagem do aviso
			$msgKey = $isNovo ? "salvoComSucesso" : "alteradoComSucesso";
			$this->addGrowlMsgs( Messages::get( $msgKey, array( "{objeto}" => $tipoPermissao['nome']."(Perfil de Permissões)")) );
			// Redireciona para index do controller 
			$this->redirect->goToUrl("permissao");
			exit();
			
//		// Em caso de uso indevido, define aviso e redireciona para para a index do controller
//		}else{
//			$this->addGrowlMsgs( Messages::get("requisicaoInvalida") );
//			$this->redirect->goToUrl("permissao");
//			exit();
//		}
			
	}
		
}
?>